package com.ansion.baseui.base.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.ViewGroup;

import androidx.annotation.NonNull;

import com.ansion.baseui.R;
import com.ansion.baseui.base.view.photoview.Attacher;
import com.ansion.baseui.base.view.photoview.OnViewTapListener;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.generic.GenericDraweeHierarchyInflater;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.facebook.imagepipeline.systrace.FrescoSystrace;


/**
 * fix: 修复某些机型下 placeholder 无法居中
 * 不要直接使用本类，建议通过 RoundFrescoView 来加载圆图
 * 默认图通过 uri 来加载
 * Uri uri = new Uri.Builder()
 * .scheme(UriUtil.LOCAL_RESOURCE_SCHEME) // "res"
 * .path(String.valueOf(R.drawable.meet_thumbnail_default))
 * .build();
 * RoundFrescoView.setImageURI(uri);
 * <p>
 * 或者
 * RoundFrescoView.setImageResource(R.drawable.meet_thumbnail_default)
 */
public class SimpleDraweeViewFix extends SimpleDraweeView {

    private Attacher mAttacher;
    private boolean mEnableDraweeMatrix = true;
    private boolean isZoom;

    public SimpleDraweeViewFix(Context context, GenericDraweeHierarchy hierarchy) {
        super(context, hierarchy);
        init(context, null, 0);
    }

    public SimpleDraweeViewFix(Context context) {
        super(context);
        init(context, null, 0);
    }

    public SimpleDraweeViewFix(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public SimpleDraweeViewFix(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyleRes) {
        TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SimpleDraweeViewFix, defStyleRes, 0);
        isZoom = attributes.getBoolean(R.styleable.SimpleDraweeViewFix_zoom, false);
        attributes.recycle();

        if (isZoom) {
            initZoom();
        }
    }

    public void setZoom(boolean zoom) {
        isZoom = zoom;
        if (isZoom) {
            initZoom();
        } else if (mAttacher != null) {
            mAttacher.setZoomable(false);
            mAttacher = null;
        }
    }

    public void setOnViewTapListener(OnViewTapListener onViewTapListener) {
        if (mAttacher != null) {
            mAttacher.setOnViewTapListener(onViewTapListener);
        }
    }

    //------------------zoom-------------------------
    protected void initZoom() {
        if (mAttacher == null || mAttacher.getDraweeView() == null) {
            mAttacher = new Attacher(this);
            mAttacher.setZoomable(true);
        }
    }

    public float getScale() {
        if (mAttacher != null) {
            return mAttacher.getScale();
        }

        return 0f;
    }

    public boolean isZoom() {
        return isZoom;
    }

    @Override
    protected void onDetachedFromWindow() {
        if (mAttacher != null) {
            mAttacher.onDetachedFromWindow();
        }
        super.onDetachedFromWindow();
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        int saveCount = canvas.save();
        if (mEnableDraweeMatrix && mAttacher != null) {
            canvas.concat(mAttacher.getDrawMatrix());
        }
        super.onDraw(canvas);
        canvas.restoreToCount(saveCount);
    }

    public void update(int imageInfoWidth, int imageInfoHeight) {
        if (mAttacher != null) {
            mAttacher.update(imageInfoWidth, imageInfoHeight);
        }
    }

    public void setImageURIWithZoom(Uri uri, int width, int height) {
        if (isZoom) {
            mEnableDraweeMatrix = false;
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    //根据View的尺寸放缩图片
                    .setResizeOptions(new ResizeOptions(width, height))
                    .setCacheChoice(ImageRequest.CacheChoice.DEFAULT)
                    .build();

            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setCallerContext(uri)
                    .setOldController(getController())
                    .setImageRequest(request)
                    .setControllerListener(new BaseControllerListener<ImageInfo>() {
                        @Override
                        public void onFailure(String id, Throwable throwable) {
                            super.onFailure(id, throwable);
                            mEnableDraweeMatrix = false;
                        }

                        @Override
                        public void onFinalImageSet(String id, ImageInfo imageInfo,
                                                    Animatable animatable) {
                            super.onFinalImageSet(id, imageInfo, animatable);
                            mEnableDraweeMatrix = true;
                            if (imageInfo != null) {
                                update(imageInfo.getWidth(), imageInfo.getHeight());
                            }
                        }

                        @Override
                        public void onIntermediateImageFailed(String id, Throwable throwable) {
                            super.onIntermediateImageFailed(id, throwable);
                            mEnableDraweeMatrix = false;
                        }

                        @Override
                        public void onIntermediateImageSet(String id, ImageInfo imageInfo) {
                            super.onIntermediateImageSet(id, imageInfo);
                            mEnableDraweeMatrix = true;
                            if (imageInfo != null) {
                                update(imageInfo.getWidth(), imageInfo.getHeight());
                            }
                        }
                    })
                    .build();

            setController(controller);
        } else {
            setImageURIWithSize(uri, width, height);
        }
    }

    //----------------------------------------------

    @Override
    protected void inflateHierarchy(Context context, AttributeSet attrs) {
        if (FrescoSystrace.isTracing()) {
            FrescoSystrace.beginSection("GenericDraweeView#inflateHierarchy");
        }
        GenericDraweeHierarchyBuilder builder =
                GenericDraweeHierarchyInflater.inflateBuilder(context, attrs);
        setAspectRatio(builder.getDesiredAspectRatio());

        Drawable mPlaceholderImage = builder.getPlaceholderImage();
        if (mPlaceholderImage instanceof BitmapDrawable) {
            ((BitmapDrawable) mPlaceholderImage).getBitmap().setDensity(context.getResources().getDisplayMetrics().densityDpi);
        }
        Drawable mFailureImage = builder.getFailureImage();
        if (mFailureImage instanceof BitmapDrawable) {
            ((BitmapDrawable) mFailureImage).getBitmap().setDensity(context.getResources().getDisplayMetrics().densityDpi);
        }

        setHierarchy(builder.build());
        if (FrescoSystrace.isTracing()) {
            FrescoSystrace.endSection();
        }
    }

    @Override
    public void setHierarchy(GenericDraweeHierarchy hierarchy) {
        super.setHierarchy(hierarchy);
    }

    public void setImageURIWithSize(Uri uri, int width, int height) {
        setImageURIWithSize(uri, width, height, ImageRequest.CacheChoice.DEFAULT);
    }

    /**
     * fix 添加 小图片icon独立缓存空间 以防因大图加载多导致小图总被清
     *
     * @param uri         图uri
     * @param width       上层view.width()
     * @param height      上层view.height()
     * @param cacheChoice ##CacheChoice
     */
    public void setImageURIWithSize(Uri uri, int width, int height, ImageRequest.CacheChoice cacheChoice) {
        if (width > 0 && height > 0) {
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    //根据View的尺寸放缩图片
                    .setResizeOptions(new ResizeOptions(width, height))
                    .setCacheChoice(cacheChoice)
                    .build();

            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setOldController(getController())
                    .setImageRequest(request)
                    .setCallerContext(uri)
                    .build();
            setController(controller);
        } else {
            super.setImageURI(uri);
        }
    }

    public void setImageURIWithAutoPlay(Uri uri, int width, int height) {
        if (width > 0 && height > 0) {
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    //根据View的尺寸放缩图片
                    .setResizeOptions(new ResizeOptions(width, height))
                    .build();

            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setOldController(getController())
                    .setImageRequest(request)
                    .setAutoPlayAnimations(true)
                    .setCallerContext(uri)
                    .build();
            setController(controller);
        } else {
            super.setImageURI(uri);
        }
    }

    public void setImageURIWithAutoPlay(Uri uri) {
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .build();

        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setOldController(getController())
                .setImageRequest(request)
                .setAutoPlayAnimations(true)
                .setCallerContext(uri)
                .build();
        setController(controller);
    }

    @Override
    public void setImageURI(Uri uri) {
        ViewGroup.LayoutParams params = getLayoutParams();
        int width = params != null ? params.width : 0;
        int height = params != null ? params.height : 0;
        if (width > 0 && height > 0) {
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    //根据View的尺寸放缩图片x
                    .setResizeOptions(new ResizeOptions(width, height))
                    .build();

            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setOldController(getController())
                    .setImageRequest(request)
                    .setCallerContext(uri)
                    .build();
            setController(controller);
        } else {
            super.setImageURI(uri);
        }
    }

    @Override
    public void setImageURI(String uriString) {
        Uri uri = (uriString != null) ? Uri.parse(uriString) : null;
        setImageURI(uri);
    }

    // 解决列表复用问题。有的情况只需要用到 placeholderImage。
    public void clear() {
        setImageURI("https://h");
    }
}
